use std::collections::HashMap;
use std::fs::File;
use std::io::BufRead;
use std::path::Path;
use std::{fs, io};

pub fn converter(input: &str) -> String {
    let wade_dict = generate_wade_dict();
    let t2c_dict = generate_t2s_dict();

    let path = Path::new("pinyin.json");
    let content = fs::read_to_string(path).unwrap();
    let pinyin_map: HashMap<&str, Vec<&str>> = serde_json::from_str(content.as_str()).unwrap();

    let mut ret: Vec<String> = Vec::new();
    for s in input.chars() {
        let pinyin =
            if let Some(pinyin) = pinyin_map.get(s.to_string().as_str()) {
                pinyin[0]
            } else if let Some(simplified) = t2s(&t2c_dict, s) {
                if let Some(pinyin) = pinyin_map.get(simplified.as_str()) {
                    pinyin[0]
                } else {
                    return "".to_string();
                }
            } else {
                return "".to_string()
            };

        if let Some(wade) = wade_dict.get(pinyin) {
            if ret.is_empty() {
                let wade = wade.chars().enumerate()
                    .map(|(i, c)| if i == 0 { c.to_uppercase().to_string() } else { c.to_string() })
                    .collect::<String>();
                ret.push(wade)
            } else {
                ret.push(wade.to_owned())
            }
        }
    }

    ret.join(" ")
}

fn t2s(t2c_dict: &HashMap<String, String>, s: char) -> Option<String> {
    if let Some(word) = t2c_dict.get(s.to_string().as_str()) {
        return Some(word.to_string());
    } else {
        for (key, value) in t2c_dict.iter() {
            if key.contains(s) {
                let start = key.find(s).unwrap();
                let end = start + s.to_string().len();
                return Some(value[start..end].to_string());
            }
        }
    }
    None
}

fn generate_wade_dict() -> HashMap<String, String> {
    let mut dict = HashMap::new();
    let file = File::open("Wade").unwrap();
    let reader = io::BufReader::new(file);
    for line in reader.lines() {
        let line = line.unwrap();
        let parts: Vec<&str> = line.split(" ").filter(|c| !c.is_empty()).collect();
        let wade = parts[0].to_string();
        let pinyin = parts[1].to_string();
        dict.insert(pinyin.clone(), wade.clone());
    }
    dict
}

fn generate_t2s_dict() -> HashMap<String, String> {
    let mut dict = HashMap::new();
    let file = File::open("STPhrases.txt").unwrap();
    let reader = io::BufReader::new(file);
    for line in reader.lines() {
        let line = line.unwrap();
        let parts: Vec<&str> = line.split("\t").collect();
        let simplified = parts[0].to_string();
        let traditional = parts[1].to_string();
        dict.insert(traditional.clone(), simplified.clone());
    }
    dict
}